package com.hongye.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;


public class HttpUtils {
	
	private static Logger log = Logger.getLogger(HttpUtils.class);
	
	/**
	 * HttpGet
	 * @author liushaomin
	 * 2016年10月12日
	 * @param httpget
	 * @return
	 */
	public static String executeGet(HttpGet httpget) {
		HttpClient httpclient = new DefaultHttpClient();
		ResponseHandler<String> responseHandler = new BasicResponseHandler();
		try {
			return httpclient.execute(httpget, responseHandler);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			httpclient.getConnectionManager().shutdown();
		}
	}

	/**
	 * Get方式请求某个地址，返回输出的内容
	 * @param uri
	 * @return
	 * @author: liushaomin
	 */
	public static String get(String uri, String token) {
		HttpGet httpget = new HttpGet(uri);
		httpget.addHeader("Authorization", "Bearer " + token);
		return executeGet(httpget);
	}
	
	/**
	 * get 
	 * @param uri
	 * @return
	 * @author: liushaomin
	 */
	public static String get(URI uri) {
		HttpGet httpget = new HttpGet(uri);
		return executeGet(httpget);
	}

	/**
	 * 执行httpclient get方法
	 * 目前只支持http，
	 * url可以以http开头 如：https://www.baidu.com
	 * 也可以不带http 如：www.baidu.com
	 * @param url
	 * @param map
	 * @return
	 * @author: liushaomin
	 */
	public static String get(String url, Map<String, String> map) {
		URIBuilder builder = new URIBuilder();
		if (url.startsWith("http")) {
			builder.setPath(url);
		}else {
			builder.setScheme("http").setHost(url);
		}
		for (Map.Entry<String, String> entry : map.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			builder.setParameter(key, value);
		}
		try {
			return get(builder.build());
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 执行httpclient Post方法,URL以http开头
	 * http://api2.santo.cc/submit
	 * @author liushaomin
	 * 2016年10月4日
	 * @param url
	 * @param map
	 * @return
	 */
	public static String post(String url, Map<String, String> map) {
		URIBuilder builder = new URIBuilder();
		builder.setPath(url);
		for (Map.Entry<String, String> entry : map.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			builder.setParameter(key, value);
		}
		try {
			return Post(builder.build());
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * Post方式请求某个地址，返回输出的内容
	 * @author liushaomin
	 * 2016年10月4日
	 * @param uri
	 * @return
	 */
	public static String Post(URI uri) {
		HttpPost httppost = new HttpPost(uri);
		HttpClient httpclient = new DefaultHttpClient();
		ResponseHandler<String> responseHandler = new BasicResponseHandler();
		try {
			return httpclient.execute(httppost, responseHandler);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			httpclient.getConnectionManager().shutdown();
		}
	}
	
	/**
	 * 封装url参数  返回url
	 * @author liushaomin
	 * 2016年10月12日
	 * @param url
	 * @param map
	 * @return
	 */
	public static URI Parameter(String url, Map<String, String> map) {
		URIBuilder builder = new URIBuilder();
		builder.setPath(url);
		for (Map.Entry<String, String> entry : map.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			builder.setParameter(key, value);
		}
		try {
			return builder.build();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * HttpURLConnection 发送请求
	 * @author liushaomin
	 * 2016年10月12日
	 * @param urlstr
	 * @param params JSONObject
	 * @param mothod
	 * @param token
	 * @return
	 */
	public static String HttpURL(String urlstr, JSONObject params, String mothod, String token){
		StringBuffer sb = new StringBuffer("");
		try {
			URL url = new URL(urlstr);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod(mothod);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type","application/json");
            connection.setRequestProperty("Authorization", token);
            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.connect();
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
    		out.write(params.toString().getBytes("UTF-8"));
    		out.flush();
            out.close();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String lines;
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes("UTF-8"));
                sb.append(lines);
            }
            reader.close();// 断开连接
            connection.disconnect();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}
	
	/**
	* post请求
	*@author lifuqiang
	* 2016-10-21
	* @param url:
	* @param params：
	*/
	public static String sendPost(String url, Map<String, String> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;        
        StringBuilder result = new StringBuilder(); 
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn =(HttpURLConnection) realUrl.openConnection();
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // POST方法
            conn.setRequestMethod("POST");
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect();
            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            // 发送请求参数            
            if (params != null) {
		          StringBuilder param = new StringBuilder(); 
		          for (Map.Entry<String, String> entry : params.entrySet()) {
		        	  if(param.length()>0){
		        		  param.append("&");
		        	  }
		        	  param.append(entry.getKey());
		        	  param.append("=");
		        	  param.append(entry.getValue());
		          }
		          out.write(param.toString());
            }
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) { 
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result.toString();
    }

	/**
	 * post请求  xml
	 * @author liushaomin
	 * 2017年2月16日
	 * @param urlStr
	 * @param xmlInfo
	 * @return
	 */
	public static String sendPostXml(String urlStr, String xmlInfo) {
		StringBuilder result = new StringBuilder();
        try {
            URL url = new URL(urlStr);
            URLConnection con = url.openConnection();
            con.setDoOutput(true);
            con.setRequestProperty("Content-Type", "text/xml");
            OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(),"UTF-8");
            out.write(new String(xmlInfo));
            out.flush();
            out.close();
            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
            String line ;
            while ((line = br.readLine()) != null) {
                result.append(line);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
		return result.toString();
    }  
	
    /**
     * 字符串编码转换的实现方法
     * @param str    待转换的字符串
     * @param oldCharset    源字符集
     * @param newCharset    目标字符集
     */
    public static String changeCharset(String str, String oldCharset, String newCharset) throws UnsupportedEncodingException {
        if(str != null) {
            //用源字符编码解码字符串
            byte[] bs = str.getBytes(oldCharset);
            return new String(bs, newCharset);
        }
        return null;
    }
    
    /**
     * 请求微信退款接口 需要证书
     * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 
     * @param url    请求的url
     * @param xmlrefund 退款需要的xml参数
     */
    public static String doRefund(String url, String xmlrefund) throws Exception {  
        KeyStore keyStore  = KeyStore.getInstance("PKCS12");
        URL file_url = new URL("http://120.27.117.192/rbg/doc/weinxin/apiclient_cert.p12");
        BufferedInputStream instream = new BufferedInputStream(file_url.openStream());
        try {
            keyStore.load(instream, WeixinUtils.mch_id.toCharArray());
        } finally {
            instream.close();
        }
        javax.net.ssl.SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, WeixinUtils.mch_id.toCharArray())
                .build();
        @SuppressWarnings("deprecation")
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[] { "TLSv1" },
                null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        try {
            HttpPost httpost = new HttpPost(url); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com ");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(xmlrefund, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
               return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}
